{
  "openapi": "3.1.0",
  "info": {
    "title": "共有リソース オープン API",
    "description": "MoreLogin オープン API を介して共有リソース（プロキシ、グループ、タグ）を管理します。\n\n**ベース URL**: `https://api.morelogin.com`\n\n認証は OAuth2 Bearer トークンを介して行われます。詳細は [認証](../Getting%20Started/authentication.md) を参照してください。\n",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxy Management",
      "description": "プロキシ設定の作成、更新、削除、および一覧表示"
    },
    {
      "name": "Group Management",
      "description": "環境グループの作成、更新、削除、および一覧表示"
    },
    {
      "name": "Tag Management",
      "description": "環境タグの作成、更新、削除、および一覧表示"
    },
    {
      "name": "Webhook Management",
      "description": "Webhook イベントを受け取るチームのコールバックエンドポイントを設定します"
    }
  ],
  "paths": {
    "/proxyInfo/page": {
      "post": {
        "summary": "プロキシの一覧を取得する",
        "deprecated": false,
        "description": "チームのプロキシ設定をページ単位で一覧します。\n- **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。\n- **補足**：一般メンバー、およびクラウドプロキシとダイナミックプロキシについてはパスワードが返されません。ダイナミックプロキシはここに現れますが、管理は別の場所で行われ、プロキシ系エンドポイントから編集することはできません。",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "完全一致で検索する任意のプロキシ ID。精度の低下を避けるため、64 ビット ID は 10 進数の文字列で渡してください。省略時は ID で絞り込みません。他の絞り込み条件とページ指定も適用されます。",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "現在のページ番号（1 から開始）",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "1 ページあたりの件数",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "クラウドフォン用のプロキシかどうか。\n- `true`: ローカル / プライベート IP を除外します（例：127.0.0.1、360、pia、プライベート範囲）\n- `false`: すべてのプロキシを返します\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "プロキシの区分：\n- `1` = クラウドプラットフォーム\n- `2` = 自己所有 IP\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "プロキシの IP アドレスで絞り込み（部分一致）",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "プロキシ名で絞り込み（部分一致）",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "プロキシ種別 ID の一覧。指定できる値：\n- `0` = なし\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "プロキシの割り当て状態：\n- `0` = 正常\n- `1` = 未割り当て\n- `2` = アップグレード中\n- `3` = 期限切れ\n- `4` = 期限切れ間近  \n> 注意：自己所有のプロキシは常に状態 `1` になります。\n",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "プロキシの検査状態：\n- `0` = 保留中\n- `1` = 成功\n- `2` = 失敗\n- `3` = 不明なエラー\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "プロキシのプロトコル種別：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` は要求されたページのレコードで、一致するものがない場合は空配列です。`data.total`、`data.current`、`data.pages` はページング情報を示します。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "有効期限",
                                "type": "string"
                              },
                              "id": {
                                "description": "主キー",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "プロキシ種別：1 - プラットフォームのプロキシ、2 - 自己所有のプロキシ",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "検査状態：0 - 検査待ち、1 - 検査成功、2 - 検査失敗、3 - 不明なエラー",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "プロキシの州または都道府県。出口 IP の検出地域を優先し、なければ設定地域を使用します。null または空文字列の場合があります。",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "プロキシの都市。出口 IP の検出地域を優先し、なければ設定地域を使用します。null または空文字列の場合があります。",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "プロキシ接続ポート。プロキシ名から推測しません。取得できない場合は null になります。",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "プロキシ IP",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "出口 IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "countryCode",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "プロキシ名",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "プロキシ種別：デフォルト値 0 - なし 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan，11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "プロキシ種別：0 - http、1 - https、2 - socks5、3 - ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "プロキシのユーザー名",
                                "type": "string"
                              },
                              "password": {
                                "description": "プロキシのパスワード",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "プロキシの更新 URL",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/add": {
      "post": {
        "summary": "プロキシを追加する",
        "deprecated": false,
        "description": "チーム内にプロキシ設定を作成します。\n- **前提条件**：`proxyPort` は必須で 1〜65535 の範囲、`proxyProvider` は認識されるデバイスサービスである必要があります。\n- **副作用**：プロキシレコードを挿入し、その ID を返します。そのままプロファイルへ紐付けできます。プロキシ事業者側へは何も送信されません。\n- **完了シグナル**：同期的です。\n- **リトライ**：**名前や設定の一意性チェックはありません。** 同じリクエストボディを 2 回送ると、ID の異なるプロキシが 2 件作られます。タイムアウト後は再送前に `/proxyInfo/page` を検索してください。\n\n文書化されたビジネスエラー: `14023`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "市区町村",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "国コード（ISO 3166-1 alpha-2）。proxyProvider=17 の場合にのみ必須です。\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "暗号化方式。有効な値は 1 から 14 までの整数です。",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "IP 変更時の動作：0 = ブロック、1 = 警告",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "IP 変更の監視を有効にする",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "プロキシ認証のパスワード",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "プロキシの IP アドレス",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "プロキシ名（{{random}} などのプレースホルダーに対応）",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "プロキシのポート番号",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "プロキシ種別の種別：\n0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH, 4=Oxylabs, 5=Proxys.io, 6=GeoSurf, 7=Luminati, 8=Lumauto, 9=Oxylabsauto, 10=Trojan, 11=Shadowsocks, 12=vmess, 13=ABCPROXY, 14=LunaProxy, 15=IPHTML, 16=PiaProxy, 17=922S5.\n特別な規則：\n- proxyProvider が 7 または 8 の場合、proxyType は必須です。\n- proxyProvider が 17 の場合、country は必須で、state と city は省略できます。\n",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "プロキシのプロトコル種別： 0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH.\nproxyProvider が 7 または 8 の場合にのみ必須です。\n",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "動的プロキシの IP を更新する URL（対応している場合）",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "都道府県/州",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "プロキシ認証のユーザー名",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は単一の integer 値です。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "プロキシ ID",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/update": {
      "post": {
        "summary": "プロキシ情報の変更",
        "deprecated": false,
        "description": "プロキシ設定を更新します。\n- **前提条件**：プロキシがチーム内に存在すること。**ダイナミックプロキシはこのエンドポイントから更新できません。** デバイスサービスは認識される値である必要があります。\n- **副作用**：これは部分更新ではなく全体上書きです — 省略したフィールドは現在の値を保持するのではなくデフォルト値に戻ります。まずプロキシを読み出し、完全な形で送り返してください。\n- **反映範囲**：変わるのはプロキシレコード自体だけなので、プロファイルの紐付けはそのまま保たれますが、既に稼働中のブラウザーやクラウドフォンは起動時の接続情報を使い続けます。新しい設定を適用するには再起動してください。\n- **完了シグナル**：同期的です。楽観ロックはないため、同時更新は後書き優先になります。\n\n文書化されたビジネスエラー: `14003`, `14023`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "プロキシの一意な ID"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "プロキシサーバーの IP アドレス"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "プロキシサーバーのポート"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "プロキシの任意の名前"
                  },
                  "country": {
                    "type": "string",
                    "description": "国（例：\"US\"、\"CN\"）"
                  },
                  "city": {
                    "type": "string",
                    "description": "都市名"
                  },
                  "username": {
                    "type": "string",
                    "description": "認証ユーザー名（必要な場合）"
                  },
                  "password": {
                    "type": "string",
                    "description": "認証パスワード（必要な場合）"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "プロキシのプロトコル種別：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "プロキシ種別 ID：\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "暗号化方式（デバイスサービス固有。通常は平文の 0）"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "IP 変更の監視を有効にする"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "IP が変わったときに取る動作：\n- `1` = 通知 / 更新（一般的な値）\n> すべての選択肢はシステムのドキュメントを参照してください。\n"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "IP の更新を実行する URL（デバイスサービスが対応している場合）"
                  },
                  "state": {
                    "type": "string",
                    "description": "予約フィールドまたは任意の状態（省略可）"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。この操作はペイロードを返しません。結果は `code` で示されます。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/proxyInfo/delete": {
      "post": {
        "summary": "プロキシを削除",
        "deprecated": false,
        "description": "1 つ以上のプロキシ設定を削除します。\n- **前提条件**：少なくとも 1 つの ID がチーム内で解決できること。解決できないものは黙って無視されます。**期限切れでないクラウドプラットフォームプロキシは削除できず**、専用のエラーで報告されます。\n- **副作用**：自前のプロキシは削除され、踏み台サーバーとの紐付けも解除されます。期限切れのクラウドプラットフォームプロキシは、代わりに解放待ちとしてマークされ、そのサブスクリプションが解約され、IP は**非同期に**解放されます — レスポンスが返る時点でも解放処理が進行中の可能性があります。\n- **連鎖影響**：そのプロキシに紐付いたプロファイルとクラウドフォンは、**ブロックも解除もされません**。削除済みのプロキシを指し続け、稼働中のセッションも中断されません。削除前に `/env/setProxy/batch` で紐付け替えてください。\n- **リトライ**：ID は 1 件ずつ処理され、最初の拒否で中断するため、バッチが部分的にのみ適用され得ます。リトライ前に `/proxyInfo/page` を読み直してください。\n\n文書化されたビジネスエラー: `14017`, `14024`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxy Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。この操作はペイロードを返しません。結果は `code` で示されます。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/page": {
      "post": {
        "operationId": "envgroupPagePost",
        "summary": "グループのリストを取得する",
        "deprecated": false,
        "description": "プロファイルグループをページ単位で一覧します。\n- **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。\n- **補足**：チームがグループ単位でアクセスを認可している場合、グループの付与が一切ないメンバーにはエラーではなく空のページが返ります。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "グループ名（部分一致）"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "現在のページ"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "1 ページあたりの件数"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` は要求されたページのレコードで、一致するものがない場合は空配列です。`data.total`、`data.current`、`data.pages` はページング情報を示します。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "グループ ID",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "グループ名",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/edit": {
      "post": {
        "operationId": "envgroupEditPost",
        "summary": "グループ情報を変更する",
        "deprecated": false,
        "description": "プロファイルグループをリネームします。\n- **前提条件**：グループがチーム内に存在し、呼び出し元がそれに対する権限を持ち、新しい名前が他のグループと衝突しないこと。一意性チェックは名前が実際に変わる場合にのみ実行されます。\n- **副作用**：グループをリネームします。プロファイルはそのまま残ります — プロファイルはグループを ID で参照するため、他に更新すべきものはありません。\n- **完了シグナル**：同期的かつ冪等です。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "環境グループの新しい名前"
                  },
                  "id": {
                    "type": "string",
                    "description": "更新対象グループの一意な ID"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は単一の boolean 値です。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "結果"
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/create": {
      "post": {
        "operationId": "envgroupCreatePost",
        "summary": "グループを追加",
        "deprecated": false,
        "description": "プロファイルグループを作成します。\n- **前提条件**：名前は空でなく、100 文字以内で、チーム内の既存グループと重複しないこと。**1 チームあたり 1000 グループまでです。**\n- **副作用**：グループを作成します。チームがグループ単位でアクセスを認可しており、呼び出し元がオーナーでない場合、呼び出し元にも新しいグループへのアクセス権が付与されます。\n- **完了シグナル**：同期的です。`data` に新しいグループ ID が入ります。\n- **リトライ**：名前の重複は既存グループの再利用ではなく拒否として扱われます。したがって「実際は成功したがレスポンスを受け取れなかった」後のリトライは重複名エラーになり、それが 1 回目が成功した証拠になります。`/envgroup/page` で確認してください。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は `id`、`groupName` のフィールドを持つオブジェクトです。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "この操作が返すデータ",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "グループ ID",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "グループ名",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envgroup/delete": {
      "post": {
        "operationId": "envgroupDeletePost",
        "summary": "グループを削除",
        "deprecated": false,
        "description": "1 つ以上のプロファイルグループを削除します。\n- **前提条件**：少なくとも 1 つの ID がチーム内で解決でき、呼び出し元がそれに対する権限を持つこと。解決できない ID は黙って無視されます。\n- **副作用**：グループとそのメンバーアクセス権を削除します。そこに属していたブラウザープロファイルとクラウドフォンは未グループになるため、宙に浮いたグループ参照は残りません。環境も削除するフラグを立てた場合は、権限のあるプロファイルを追加で**ゴミ箱へ移動**します — それらは破棄されず、またこのフラグはクラウドフォンには一切影響しません。\n- **完了シグナル**：同期的ですが**原子的ではありません**。グループが先に削除され、後続のステップは依然失敗し得ます。例えばプロファイルが起動中または移管中の場合、グループは消えたのにプロファイルは移動していない状態になります。\n- **リトライ**：リトライ前に `/envgroup/page` とプロファイル一覧で確認してください。\n\n文書化されたビジネスエラー: `19064`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "tags": [
          "Group Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "更新対象グループの一意な ID"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "グループ内の環境を削除しますか？false：削除しない、true：削除する"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は単一の boolean 値です。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/all": {
      "get": {
        "operationId": "envtagAllGet",
        "summary": "タグのリストを取得する",
        "deprecated": false,
        "description": "チーム内のすべてのプロファイルタグを返します。\n- **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。\n- **補足**：このエンドポイントは**ページングされず、タグにはサーバー側の上限もありません**。したがってレスポンスはチームが作成したタグ数に応じて大きくなります。クライアント側の設計で考慮してください。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "成功。`data` は `id`、`tagName` のフィールドを持つオブジェクトの配列で、返すものがない場合は空配列になります。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "タグ ID",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "タグ名",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/create": {
      "post": {
        "operationId": "envtagCreatePost",
        "summary": "タグを作成する",
        "deprecated": false,
        "description": "プロファイルタグを作成します。\n- **前提条件**：名前は空でなく、100 文字以内で、チーム内の既存タグと重複しないこと。\n- **副作用**：タグを作成し、その ID を返します。グループと異なり、タグには件数上限がありません。\n- **リトライ**：名前の重複は既存タグの再利用ではなく拒否として扱われます。`/envtag/all` で確認してください。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "タグ名"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は `id`、`tagName` のフィールドを持つオブジェクトです。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "タグ ID",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "タグ名",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/edit": {
      "post": {
        "operationId": "envtagEditPost",
        "summary": "タグの情報を変更する",
        "deprecated": false,
        "description": "プロファイルタグをリネームします。\n- **前提条件**：タグがチーム内に存在し、新しい名前が他のタグと衝突しないこと。\n- **副作用**：タグをリネームします。既存のタグの紐付けは影響を受けず、プロファイルには即座に新しい名前が表示されます。\n- **完了シグナル**：同期的かつ冪等です。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "タグ id"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "タグ名"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は単一の boolean 値です。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/envtag/delete": {
      "post": {
        "operationId": "envtagDeletePost",
        "summary": "タグを削除",
        "deprecated": false,
        "description": "1 つ以上のプロファイルタグを削除します。\n- **前提条件**：少なくとも 1 つの ID がチーム内で解決できること。解決できないものは黙って無視されます。\n- **副作用**：タグを削除します。そのタグは付いていたすべてのプロファイルから消え、プロファイル自体は削除されません。このエンドポイントはプロファイルタグのみを管理します — クラウドストレージのファイルタグは別に管理されます。\n- **完了シグナル**：同期的です。再呼び出しではタグが無効と報告され、これは 1 回目が成功したことを意味します。\n\n文書化されたビジネスエラー: `19105`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "tags": [
          "Tag Management"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "更新するタグの一意な ID"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は単一の boolean 値です。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    },
    "/webhook/config": {
      "post": {
        "operationId": "webhookConfigPost",
        "summary": "チームの Webhook を設定",
        "deprecated": false,
        "description": "チームの Webhook 設定を作成または置き換えます。\n\n- **前提条件**：`callbackUrl` は 1〜1024 文字の HTTPS URL で、ホスト名を持ち、ユーザー情報とフラグメントを含まず、ポートが正しい必要があります。解決先のすべてのアドレスが公開経路である必要があり、localhost、プライベート、リンクローカル、CGNAT、クラウドメタデータ、プロトコル予約、ドキュメント用、6to4 などの範囲は拒否されます。実際に接続する時点でも同じ検査を行うため、後からプライベート範囲に解決される名前は、その配信が失敗するだけで、あなたのネットワークには到達しません。\n- **副作用**：サーバー側コンテキストのチームが持つ唯一の設定を upsert します。`teamId` はリクエストから読み取らないため、他チームの設定はできません。Local API と Open API は同じレコードを読み書きし、レスポンスは保存内容をそのまま返します。\n- **停止**：`enabled: false` は URL を保持したまま、新しいイベントの作成を止めます。すでにキューにあるイベントは、次に承認される時点で設定がまだ停止中であれば 1 件ずつキャンセルされます。すぐに再有効化すれば、そのまま配信が続きます。\n- **リトライ**：安全です。保存はチーム単位の upsert なので、同じリクエストを繰り返しても同じ状態に収束します。\n\nコールバック契約、イベント名、リトライ間隔は [Webhooks](../Getting%20Started/webhooks.md) を参照してください。\n\n文書化されたビジネスエラー: `41001`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md) を参照してください。どの操作でも共通コードが返る場合があります。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "イベントを受け取る HTTPS URL。1〜1024 文字。",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "このチームで配信を有効にするかどうか。",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` は `callbackUrl` と `enabled` を持つオブジェクトで、保存された設定をそのまま返します。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "戻り結果コード。0 は正常、それ以外は例外を示します。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "エラーメッセージ",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "保存されている HTTPS コールバック URL。",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "このチームで配信を有効にするかどうか。",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作リクエスト ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        }
      }
    }
  },
  "webhooks": {
    "cloud_phone.power_on": {
      "post": {
        "operationId": "webhookCloudPhonePowerOn",
        "summary": "クラウドフォンの起動が完了",
        "description": "起動が最終結果に達した時点で送信されます。\n\n`success` が `true` になるのは、デバイスサービスのコールバックが成功し、ローカル同期がコミットされた場合のみです。起動時の課金失敗、または非同期のプロキシ検査が失敗して後処理まで完了した場合は起動失敗として報告され、別途停止イベントは発生しません。プリセットアプリのインストールなど後回しにされた処理は、この結果を変更しません。\n\n起動中に停止操作で中断された場合、その試行では起動イベントは作成されません。その後に停止が成功すれば、独立した `cloud_phone.power_off` が作成されます。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_phone.power_on",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": false,
                  "code": "33318",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.power_off": {
      "post": {
        "operationId": "webhookCloudPhonePowerOff",
        "summary": "クラウドフォンが停止",
        "description": "停止が成功したときに送信されます。停止が失敗した場合このイベントは作成されないため、ここでの `result.success` は常に `true` です。\n\n`data.reason` に停止理由が入ります。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhonePowerOffWebhookEvent"
              },
              "example": {
                "eventId": "5b1d0c9e7a2f4d38b6c5a4e3f2d1c0b9",
                "eventType": "cloud_phone.power_off",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001",
                  "reason": "MONEY_SAVING"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.restart": {
      "post": {
        "operationId": "webhookCloudPhoneRestart",
        "summary": "クラウドフォンの再起動が完了",
        "description": "再起動が最終結果に達した時点で送信されます。`success` が `true` になるのは、デバイスサービスのコールバックが成功し、ローカル同期がコミットされた場合のみです。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "9e4c1a7b3f2d40518a6b5c4d3e2f1a0b",
                "eventType": "cloud_phone.restart",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.reset": {
      "post": {
        "operationId": "webhookCloudPhoneReset",
        "summary": "クラウドフォンのリセットが完了",
        "description": "リセットが最終結果に達した時点で送信されます。`success` が `true` になるのは、デバイスサービスのコールバックが成功し、ローカル同期がコミットされた場合のみです。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "2f8a6d4c0b9e47138c7d6e5f4a3b2c1d",
                "eventType": "cloud_phone.reset",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_phone.new_machine": {
      "post": {
        "operationId": "webhookCloudPhoneNewMachine",
        "summary": "クラウドフォンのワンクリック新規端末化が完了",
        "description": "ワンクリック新規端末化の操作が最終結果に達した時点で送信されます。`success` が `true` になるのは、デバイスサービスのコールバックが成功し、ローカル同期がコミットされた場合のみです。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudPhoneWebhookEvent"
              },
              "example": {
                "eventId": "7c3b1e9d5a4f42068b1c2d3e4f5a6b70",
                "eventType": "cloud_phone.new_machine",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudPhoneId": "20001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.start": {
      "post": {
        "operationId": "webhookCloudBrowserStart",
        "summary": "クラウドブラウザーの起動が完了",
        "description": "クラウドブラウザーの起動が最終結果に達した時点で送信されます。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserWebhookEvent"
              },
              "example": {
                "eventId": "4a9f2c7e1b8d43509c6a5b4c3d2e1f00",
                "eventType": "cloud_browser.start",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001"
                },
                "result": {
                  "success": true,
                  "code": "0",
                  "message": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    },
    "cloud_browser.stop": {
      "post": {
        "operationId": "webhookCloudBrowserStop",
        "summary": "クラウドブラウザーの停止が完了",
        "description": "クラウドブラウザーの停止は、成功・失敗にかかわらず毎回送信されます。停止失敗状態に入ること自体がその試行の失敗結果です。その後の手動リトライや強制解放は新しい操作として扱われ、新しい `eventId` が発行されます。\n\nイベントは停止操作単位で重複排除されるため、1 回の試行から 2 つのイベントが出ることはなく、2 回の試行がまとめられることもありません。内部のアーカイブ失敗は `result` のみに影響し、停止開始時に確定した `reason` を上書きすることはありません。",
        "tags": [
          "Webhook Management"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEventId"
          },
          {
            "$ref": "#/components/parameters/WebhookEventType"
          },
          {
            "$ref": "#/components/parameters/WebhookUserAgent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloudBrowserStopWebhookEvent"
              },
              "example": {
                "eventId": "c7f3a2b10d8e4f6a9c1b2d3e4f5a6b7c",
                "eventType": "cloud_browser.stop",
                "eventTime": "1787241600000",
                "data": {
                  "teamId": "10001",
                  "cloudBrowserId": "30001",
                  "runId": "40001",
                  "reason": "BROWSER_EXITED"
                },
                "result": {
                  "success": false,
                  "code": "40006",
                  "message": "Operation failed"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookAck"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Authorization": {
        "type": "http",
        "description": "アクセストークン取得インターフェースのレスポンスの access_token フィールドの値",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "parameters": {
      "WebhookEventId": {
        "name": "X-Webhook-Event-Id",
        "in": "header",
        "required": true,
        "description": "本文の `eventId` と同じ値です。ハンドラーを冪等にするために使用してください。",
        "schema": {
          "type": "string"
        }
      },
      "WebhookEventType": {
        "name": "X-Webhook-Event-Type",
        "in": "header",
        "required": true,
        "description": "本文の `eventType` と同じ値なので、解析せずにルーティングできます。",
        "schema": {
          "type": "string"
        }
      },
      "WebhookUserAgent": {
        "name": "User-Agent",
        "in": "header",
        "required": true,
        "description": "常に `MoreLogin-Webhook/1.0` です。",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "WebhookAck": {
        "description": "2xx はすべて配信成功として扱われます。レスポンス本文は無視されるため、できるだけ早く応答し、実処理は非同期で行ってください。それ以外は、接続タイムアウトや読み取りタイムアウトを含めてすべて失敗として再試行されます。"
      }
    },
    "schemas": {
      "WebhookResult": {
        "type": "object",
        "description": "このイベントが表す操作の最終結果です。",
        "properties": {
          "success": {
            "description": "この操作が最終的に成功したかどうか。",
            "type": "boolean"
          },
          "code": {
            "description": "成功時は `0`。失敗時は言語に依存しない安定したビジネスエラーコードです。",
            "type": "string"
          },
          "message": {
            "description": "成功時は `null`。失敗時はチームの言語による説明で、その言語や文言が利用できない場合は `en-US` にフォールバックします。",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "success",
          "code",
          "message"
        ]
      },
      "CloudPhoneWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "一意のイベント ID。同じイベントの再送や内部リプレイでも同じ値が使われるため、冪等キーとして扱ってください。",
            "type": "string"
          },
          "eventType": {
            "description": "安定したイベント名です。",
            "type": "string"
          },
          "eventTime": {
            "description": "業務上の最終結果が発生した時刻。Unix エポックのミリ秒で、文字列として送信されます。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "このリソースを所有するチームです。",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "このイベントの対象となるクラウドフォンです。",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudPhonePowerOffWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "一意のイベント ID。同じイベントの再送や内部リプレイでも同じ値が使われるため、冪等キーとして扱ってください。",
            "type": "string"
          },
          "eventType": {
            "description": "安定したイベント名です。",
            "type": "string"
          },
          "eventTime": {
            "description": "業務上の最終結果が発生した時刻。Unix エポックのミリ秒で、文字列として送信されます。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "このリソースを所有するチームです。",
                "type": "string"
              },
              "cloudPhoneId": {
                "description": "このイベントの対象となるクラウドフォンです。",
                "type": "string"
              },
              "reason": {
                "description": "停止した理由です。",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudPhoneId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "一意のイベント ID。同じイベントの再送や内部リプレイでも同じ値が使われるため、冪等キーとして扱ってください。",
            "type": "string"
          },
          "eventType": {
            "description": "安定したイベント名です。",
            "type": "string"
          },
          "eventTime": {
            "description": "業務上の最終結果が発生した時刻。Unix エポックのミリ秒で、文字列として送信されます。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "このリソースを所有するチームです。",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "このイベントの対象となるクラウドブラウザーのプロファイルです。",
                "type": "string"
              },
              "runId": {
                "description": "このイベントの対象となる実行インスタンスです。",
                "type": "string"
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      },
      "CloudBrowserStopWebhookEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "description": "一意のイベント ID。同じイベントの再送や内部リプレイでも同じ値が使われるため、冪等キーとして扱ってください。",
            "type": "string"
          },
          "eventType": {
            "description": "安定したイベント名です。",
            "type": "string"
          },
          "eventTime": {
            "description": "業務上の最終結果が発生した時刻。Unix エポックのミリ秒で、文字列として送信されます。",
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "teamId": {
                "description": "このリソースを所有するチームです。",
                "type": "string"
              },
              "cloudBrowserId": {
                "description": "このイベントの対象となるクラウドブラウザーのプロファイルです。",
                "type": "string"
              },
              "runId": {
                "description": "このイベントの対象となる実行インスタンスです。",
                "type": "string"
              },
              "reason": {
                "description": "実行が停止した理由です。",
                "type": "string",
                "enum": [
                  "NORMAL",
                  "MONEY_SAVING",
                  "ENERGY_SAVING",
                  "BROWSER_EXITED",
                  "OTHER"
                ]
              }
            },
            "required": [
              "teamId",
              "cloudBrowserId",
              "runId",
              "reason"
            ]
          },
          "result": {
            "$ref": "#/components/schemas/WebhookResult"
          }
        },
        "required": [
          "eventId",
          "eventType",
          "eventTime",
          "data",
          "result"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.morelogin.com",
      "description": "MoreLogin Open API のエンドポイント"
    }
  ],
  "security": [
    {
      "Authorization": []
    }
  ]
}